package com.starsea.book.ui.newpage.viewmodel

import android.app.Application
import android.text.TextUtils
import androidx.collection.arrayMapOf
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.google.gson.JsonParser
import com.starsea.book.base.BaseViewModel
import com.starsea.book.constant.AppConst
import com.starsea.book.constant.AppLog
import com.starsea.book.data.appDb
import com.starsea.book.data.entities.Book
import com.starsea.book.help.http.newCallResponseBody
import com.starsea.book.help.http.okHttpClient
import com.starsea.book.help.http.postJson
import com.starsea.book.help.http.text
import com.starsea.book.model.ReadBook
import com.starsea.book.ui.newpage.entity.MsgListEntity
import com.starsea.book.ui.newpage.entity.BaseEntity
import com.starsea.book.ui.newpage.entity.BookInfoEntity
import com.starsea.book.ui.newpage.entity.MsgTypeEntity
import com.starsea.book.ui.newpage.entity.ReadHistoryEntity
import com.starsea.book.ui.newpage.utils.gsonList
import com.starsea.book.ui.newpage.utils.gsonNormal
import com.starsea.book.utils.LogUtils
import com.starsea.book.utils.toastOnUi
import okhttp3.RequestBody.Companion.toRequestBody
import kotlin.collections.set

class MsgViewModel(application: Application) : BaseViewModel(application) {

    val msgTypeResult = MutableLiveData<BaseEntity<MutableList<MsgTypeEntity>>>()
    val msgListResult = MutableLiveData<BaseEntity<MsgListEntity>>()
    val readHistoryResult = MutableLiveData<BaseEntity<ReadHistoryEntity>>()
    val deleteReadHistoryResult = MutableLiveData<BaseEntity<String?>>()

    val addSherfResult = MutableLiveData<BaseEntity<Boolean>>()

    fun deleteReadHis(recordIds: String) {
        execute {
            okHttpClient.newCallResponseBody {
                url(AppConst.BASE_URL.plus("front-api/book-read/readBookHistoryDel?recordIds=${recordIds}"))
                    .post("".toRequestBody())
            }.text().let {
                LogUtils.e(":>>>", ">>.${it}")
                val baseEntity = BaseEntity<String?>()

                val objects = JsonParser.parseString(it).asJsonObject
                baseEntity.status = objects.get("status").asInt
                baseEntity.msg = objects.get("msg").asString
                deleteReadHistoryResult.postValue(baseEntity)
            }
        }.onError {
            context.toastOnUi(it.localizedMessage ?: "ERROR")
        }
    }

    fun getMsgType() {
        execute {
            okHttpClient.newCallResponseBody {
                url(AppConst.BASE_URL.plus("front-api/notices/findNewsType"))
                    .post("".toRequestBody())
            }.text().let {
                LogUtils.e(":>>>", ">>.${it}")
                val entity: BaseEntity<MutableList<MsgTypeEntity>> =
                    it.gsonList(MsgTypeEntity::class.java)
                msgTypeResult.postValue(entity)
            }
        }.onError {
            context.toastOnUi(it.localizedMessage ?: "ERROR")
        }
    }

    fun getMsgList(newsType: Int, pageNo: Int) {
        val map: MutableMap<String, String> = arrayMapOf()
        map["newsType"] = newsType.toString()
        map["pageNo"] = pageNo.toString()
        map["pageSize"] = 10.toString()
        val json = Gson().toJson(map)
        execute {
            okHttpClient.newCallResponseBody {
                url(AppConst.BASE_URL.plus("front-api/notices/findNewsList"))
                    .postJson(json)
            }.text().let {
                LogUtils.e(">>>", ">>.${it}")
                val entity: BaseEntity<MsgListEntity> =
                    it.gsonNormal(MsgListEntity::class.java)
                msgListResult.postValue(entity)
            }
        }.onError {
            context.toastOnUi(it.localizedMessage ?: "ERROR")
        }
    }

    fun readAll() {
        execute {
            okHttpClient.newCallResponseBody {
                url(AppConst.BASE_URL.plus("front-api/notices/readAll"))
                    .post("".toRequestBody())
            }.text().let {
                LogUtils.e(">>>", ">>.${it}")

            }
        }.onError {
            context.toastOnUi(it.localizedMessage ?: "ERROR")
        }
    }

    fun getReadHistory(pageNo: Int) {
        val map: MutableMap<String, String> = arrayMapOf()
        map["pageNo"] = pageNo.toString()
        map["pageSize"] = 10.toString()
        val json = Gson().toJson(map)
        execute {
            okHttpClient.newCallResponseBody {
                url(AppConst.BASE_URL.plus("front-api/book-read/readBookHistoryPage"))
                    .postJson(json)
            }.text().let {
                LogUtils.e(":>>>", ">>.${it}")
                val entity: BaseEntity<ReadHistoryEntity> =
                    it.gsonNormal(ReadHistoryEntity::class.java)
                readHistoryResult.postValue(entity)
            }
        }.onError {
            context.toastOnUi(it.localizedMessage ?: "ERROR")
        }
    }

    fun addToShelf(
        bookId: String,
        sectionId: String = "",
        sectionTitle: String = ""
    ) {
        var url = AppConst.BASE_URL.plus("front-api/bookShelf/favorBook?bookId=${bookId}")
        if (!TextUtils.isEmpty(sectionId)) {
            url = url.plus("&sectionId=${sectionId}&sectionTitle=${sectionTitle}")
        }
        execute {
            okHttpClient.newCallResponseBody {
                url(url)
                    .post("".toRequestBody())
            }.text().let {
                LogUtils.e(">>>", ">>.${it}")
                val entity: BaseEntity<Boolean> =
                    it.gsonNormal(Boolean::class.java)
                addSherfResult.postValue(entity)
            }
        }.onError {
            context.toastOnUi(it.localizedMessage ?: "ERROR")
        }
    }


    val bookData = MutableLiveData<Book>()

    val bookInfoResult = MutableLiveData<BaseEntity<BookInfoEntity>>()
    fun getBookInfo(bookId: String) {
        execute {

            okHttpClient.newCallResponseBody {
                val map: MutableMap<String, String> = arrayMapOf()
                map["bookId"] = bookId
                url(AppConst.BASE_URL.plus("front-api/book-read/book_read_detail?bookId=${bookId}"))
                    .post("".toRequestBody())
            }.text().let {

                LogUtils.e(">>>>> ", it)
                val entity: BaseEntity<BookInfoEntity> =
                    it.gsonNormal(BookInfoEntity::class.java)

                if (entity.status != 200) {
                    bookInfoResult.postValue(entity)
                } else {
                    val book = Book(
                        name = entity.data!!.bookTitle.toString(),
                        author = entity.data!!.authorName.toString(),
                        kind = "",
                        bookUrl = entity.data!!.bookId.toString(),
                        origin = "",
                        originName = "",
                        type = 1,
                        wordCount = entity.data!!.wordCount.toString(),
                        latestChapterTitle = "",
                        coverUrl = entity.data!!.bookCover.toString(),
                        intro = entity.data!!.bookDesc.toString(),
                        tocUrl = "",
                        originOrder = 0,
                        variable = ""
                    )
                    bookData.postValue(book)
                    bookInfoResult.postValue(entity)
                }
            }


        }.onError {
            AppLog.put(it.localizedMessage, it)
            context.toastOnUi(it.localizedMessage)
        }
    }

    fun saveBook(book: Book?, success: (() -> Unit)? = null) {

        book ?: return

        execute {
            if (book.order == 0) {
                book.order = appDb.bookDao.minOrder - 1
            }
            appDb.bookDao.getBook(book.name, book.author)?.let {
                book.durChapterPos = it.durChapterPos
                book.durChapterTitle = it.durChapterTitle
            }
            book.save()
            if (ReadBook.book?.name == book.name && ReadBook.book?.author == book.author) {
                ReadBook.book = book
            }
            LogUtils.e(">>>> ", " book.save()")
        }.onSuccess {

            LogUtils.e(">>>> ", "onSuccess")
            success?.invoke()
        }
    }


}
